|
ARD2
RC2
Airbag Reference Demonstrator using MPC5604P
|
00001 00019 #include "derivative.h" 00020 #include "compile_options.h" 00021 #include "HAL.h" 00022 #include "DSPI.h" 00023 #include "MailScheduler.h" 00024 #include "CG147.h" 00025 #include "CG147_Diag.h" 00026 #include "SBC_AL.h" 00027 #include "Utils.h" 00028 #include "MMA51xx.h" 00029 #include "SIU.h" 00030 /* 00031 ****************************************************************************** 00032 * constants 00033 ****************************************************************************** 00034 */ 00035 /******************************************************************************/ 00036 static const uint8_t cau8SBCSquibFiringStatusCmd[] = 00037 { 00038 SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, 00039 SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, 00040 SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, 00041 SBC_FIRE_COUNTER, SBC_CLEAR_FIRE_CNT }; 00042 00043 static const uint8_t cau8SBCSquibFiringStatusArg[] = 00044 { 00045 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x00, 00046 0x00 }; 00047 00049 const uint16_t cu16PresentSquibs = (SQUIB_CH0_PRESENT | /* Driver frontal airbag */ 00050 SQUIB_CH1_PRESENT | /* Driver seatbelt pre-tensioner */ 00051 SQUIB_CH2_ABSENT | /* Nothing */ 00052 SQUIB_CH3_PRESENT | /* Side-passenger frontal airbag */ 00053 SQUIB_CH4_PRESENT | /* Side-passenger seat-belt pre-tensioner */ 00054 SQUIB_CH5_ABSENT | /* Nothing */ 00055 SQUIB_CH6_PRESENT | /* left side-curtain airbag */ 00056 SQUIB_CH7_ABSENT | /* Nothing */ 00057 SQUIB_CH8_ABSENT | /* Nothing */ 00058 SQUIB_CH9_PRESENT | /* right side-curtain airbag */ 00059 SQUIB_CH10_ABSENT | /* Nothing */ 00060 SQUIB_CH11_ABSENT); /* Nothing */ 00062 const uint16_t cu16PresentSatellites = (SAT_CH0_SLOT0_PRESENT | /* Front-left accelerometer */ 00063 SAT_CH0_SLOT1_ABSENT | /* Nothing */ 00064 SAT_CH0_SLOT2_ABSENT | /* Nothing */ 00065 SAT_CH1_SLOT0_PRESENT | /* Front-right accelerometer */ 00066 SAT_CH1_SLOT1_ABSENT | /* Nothing */ 00067 SAT_CH1_SLOT2_ABSENT | /* Nothing */ 00068 SAT_CH2_SLOT0_PRESENT | /* left-side accelerometer */ 00069 SAT_CH2_SLOT1_ABSENT | /* Nothing */ 00070 SAT_CH2_SLOT2_ABSENT | /* Nothing */ 00071 SAT_CH3_SLOT0_PRESENT | /* right-side accelerometer */ 00072 SAT_CH3_SLOT1_ABSENT | /* Nothing */ 00073 SAT_CH3_SLOT2_ABSENT /* Nothing */ 00074 ); 00076 const uint16_t cu16FiredSquibs = (SQUIB_CH0_NOT_FIRED | SQUIB_CH0_NOT_FIRED 00077 | SQUIB_CH1_NOT_FIRED | SQUIB_CH2_NOT_FIRED | SQUIB_CH3_NOT_FIRED 00078 | SQUIB_CH4_NOT_FIRED | SQUIB_CH5_NOT_FIRED | SQUIB_CH6_NOT_FIRED 00079 | SQUIB_CH7_NOT_FIRED | SQUIB_CH8_NOT_FIRED | SQUIB_CH9_NOT_FIRED 00080 | SQUIB_CH10_NOT_FIRED | SQUIB_CH11_NOT_FIRED); 00082 const uint16_t cu16CrashedSatellites = (SAT_CH0_SLOT0_NOT_CRASHED 00083 | SAT_CH0_SLOT1_NOT_CRASHED | SAT_CH0_SLOT2_NOT_CRASHED 00084 | SAT_CH1_SLOT0_NOT_CRASHED | SAT_CH1_SLOT1_NOT_CRASHED 00085 | SAT_CH1_SLOT2_NOT_CRASHED | SAT_CH2_SLOT0_NOT_CRASHED 00086 | SAT_CH2_SLOT1_NOT_CRASHED | SAT_CH2_SLOT2_NOT_CRASHED 00087 | SAT_CH3_SLOT0_NOT_CRASHED | SAT_CH3_SLOT1_NOT_CRASHED 00088 | SAT_CH3_SLOT2_NOT_CRASHED); 00090 const uint8_t cu8SBCSatelliteData[] = 00091 { 00092 /* Satellite 1 */ 00093 /* PROTOCOL */0x04u, 00094 /* N_DATA_BLOCKS */0x20u, 00095 /* MANUFACTURER */0x46u, 00096 /* SENSOR_TYPE */0x01u, 00097 /* AXIS */0x00u, 00098 /* RANGE */0x09u, 00099 /* DEVCFG2 */0x00u, 00100 /* PRODUCT_REVISION */0x11u, 00101 /* DEVCFG6 */0x00u, 00102 /* PROD_DATE_1 */0x00u, 00103 /* PROD_DATE_2*/0x00u, 00104 /* SN0 */0x00u, 00105 /* SN1 */0x00u, 00106 /* SN2 */0x00u, 00107 /* SN3 */0x00u, 00108 /* INIT_RAW_OFFSET */0x00u, 00109 /* COMBINED_OFFSET_SELF_TEST */0x00u, 00110 /* AVG_SELF_TEST */0x00u, 00111 /* DEVCFG1 */0x00, 00112 /* Satellite 2 */ 00113 /* PROTOCOL */0x04u, 00114 /* N_DATA_BLOCKS */0x20u, 00115 /* MANUFACTURER */0x46u, 00116 /* SENSOR_TYPE */0x01u, 00117 /* AXIS */0x00u, 00118 /* RANGE */0x09u, 00119 /* DEVCFG2 */0x00u, 00120 /* PRODUCT_REVISION */0x11u, 00121 /* DEVCFG6 */0x00u, 00122 /* PROD_DATE_1 */0x00u, 00123 /* PROD_DATE_2*/0x00u, 00124 /* SN0 */0x00u, 00125 /* SN1 */0x00u, 00126 /* SN2 */0x00u, 00127 /* SN3 */0x00u, 00128 /* INIT_RAW_OFFSET */0x00u, 00129 /* COMBINED_OFFSET_SELF_TEST */0x00u, 00130 /* AVG_SELF_TEST */0x00u, 00131 /* DEVCFG1 */0x00, 00132 /* Satellite 3 */ 00133 /* PROTOCOL */0x04u, 00134 /* N_DATA_BLOCKS */0x20u, 00135 /* MANUFACTURER */0x46u, 00136 /* SENSOR_TYPE */0x01u, 00137 /* AXIS */0x00u, 00138 /* RANGE */0x09u, 00139 /* DEVCFG2 */0x00u, 00140 /* PRODUCT_REVISION */0x11u, 00141 /* DEVCFG6 */0x00u, 00142 /* PROD_DATE_1 */0x00u, 00143 /* PROD_DATE_2*/0x00u, 00144 /* SN0 */0x00u, 00145 /* SN1 */0x00u, 00146 /* SN2 */0x00u, 00147 /* SN3 */0x00u, 00148 /* INIT_RAW_OFFSET */0x00u, 00149 /* COMBINED_OFFSET_SELF_TEST */0x00u, 00150 /* AVG_SELF_TEST */0x00u, 00151 /* DEVCFG1 */0x00, 00152 /* Satellite 4 */ 00153 /* PROTOCOL */0x04u, 00154 /* N_DATA_BLOCKS */0x20u, 00155 /* MANUFACTURER */0x46u, 00156 /* SENSOR_TYPE */0x01u, 00157 /* AXIS */0x00u, 00158 /* RANGE */0x09u, 00159 /* DEVCFG2 */0x00u, 00160 /* PRODUCT_REVISION */0x11u, 00161 /* DEVCFG6 */0x00u, 00162 /* PROD_DATE_1 */0x00u, 00163 /* PROD_DATE_2*/0x00u, 00164 /* SN0 */0x00u, 00165 /* SN1 */0x00u, 00166 /* SN2 */0x00u, 00167 /* SN3 */0x00u, 00168 /* INIT_RAW_OFFSET */0x00u, 00169 /* COMBINED_OFFSET_SELF_TEST */0x00u, 00170 /* AVG_SELF_TEST */0x00u, 00171 /* DEVCFG1 */0x00, 00172 /* Satellite 5 */ 00173 /* PROTOCOL */0x04u, 00174 /* N_DATA_BLOCKS */0x20u, 00175 /* MANUFACTURER */0x46u, 00176 /* SENSOR_TYPE */0x01u, 00177 /* AXIS */0x00u, 00178 /* RANGE */0x09u, 00179 /* DEVCFG2 */0x00u, 00180 /* PRODUCT_REVISION */0x11u, 00181 /* DEVCFG6 */0x00u, 00182 /* PROD_DATE_1 */0x00u, 00183 /* PROD_DATE_2*/0x00u, 00184 /* SN0 */0x00u, 00185 /* SN1 */0x00u, 00186 /* SN2 */0x00u, 00187 /* SN3 */0x00u, 00188 /* INIT_RAW_OFFSET */0x00u, 00189 /* COMBINED_OFFSET_SELF_TEST */0x00u, 00190 /* AVG_SELF_TEST */0x00u, 00191 /* DEVCFG1 */0x00, 00192 /* Satellite 6 */ 00193 /* PROTOCOL */0x04u, 00194 /* N_DATA_BLOCKS */0x20u, 00195 /* MANUFACTURER */0x46u, 00196 /* SENSOR_TYPE */0x01u, 00197 /* AXIS */0x00u, 00198 /* RANGE */0x09u, 00199 /* DEVCFG2 */0x00u, 00200 /* PRODUCT_REVISION */0x11u, 00201 /* DEVCFG6 */0x00u, 00202 /* PROD_DATE_1 */0x00u, 00203 /* PROD_DATE_2*/0x00u, 00204 /* SN0 */0x00u, 00205 /* SN1 */0x00u, 00206 /* SN2 */0x00u, 00207 /* SN3 */0x00u, 00208 /* INIT_RAW_OFFSET */0x00u, 00209 /* COMBINED_OFFSET_SELF_TEST */0x00u, 00210 /* AVG_SELF_TEST */0x00u, 00211 /* DEVCFG1 */0x00, 00212 /* Satellite 7 */ 00213 /* PROTOCOL */0x04u, 00214 /* N_DATA_BLOCKS */0x20u, 00215 /* MANUFACTURER */0x46u, 00216 /* SENSOR_TYPE */0x01u, 00217 /* AXIS */0x00u, 00218 /* RANGE */0x09u, 00219 /* DEVCFG2 */0x00u, 00220 /* PRODUCT_REVISION */0x11u, 00221 /* DEVCFG6 */0x00u, 00222 /* PROD_DATE_1 */0x00u, 00223 /* PROD_DATE_2*/0x00u, 00224 /* SN0 */0x00u, 00225 /* SN1 */0x00u, 00226 /* SN2 */0x00u, 00227 /* SN3 */0x00u, 00228 /* INIT_RAW_OFFSET */0x00u, 00229 /* COMBINED_OFFSET_SELF_TEST */0x00u, 00230 /* AVG_SELF_TEST */0x00u, 00231 /* DEVCFG1 */0x00, 00232 /* Satellite 8 */ 00233 /* PROTOCOL */0x04u, 00234 /* N_DATA_BLOCKS */0x20u, 00235 /* MANUFACTURER */0x46u, 00236 /* SENSOR_TYPE */0x01u, 00237 /* AXIS */0x00u, 00238 /* RANGE */0x09u, 00239 /* DEVCFG2 */0x00u, 00240 /* PRODUCT_REVISION */0x11u, 00241 /* DEVCFG6 */0x00u, 00242 /* PROD_DATE_1 */0x00u, 00243 /* PROD_DATE_2*/0x00u, 00244 /* SN0 */0x00u, 00245 /* SN1 */0x00u, 00246 /* SN2 */0x00u, 00247 /* SN3 */0x00u, 00248 /* INIT_RAW_OFFSET */0x00u, 00249 /* COMBINED_OFFSET_SELF_TEST */0x00u, 00250 /* AVG_SELF_TEST */0x00u, 00251 /* DEVCFG1 */0x00, 00252 /* Satellite 9 */ 00253 /* PROTOCOL */0x04u, 00254 /* N_DATA_BLOCKS */0x20u, 00255 /* MANUFACTURER */0x46u, 00256 /* SENSOR_TYPE */0x01u, 00257 /* AXIS */0x00u, 00258 /* RANGE */0x09u, 00259 /* DEVCFG2 */0x00u, 00260 /* PRODUCT_REVISION */0x11u, 00261 /* DEVCFG6 */0x00u, 00262 /* PROD_DATE_1 */0x00u, 00263 /* PROD_DATE_2*/0x00u, 00264 /* SN0 */0x00u, 00265 /* SN1 */0x00u, 00266 /* SN2 */0x00u, 00267 /* SN3 */0x00u, 00268 /* INIT_RAW_OFFSET */0x00u, 00269 /* COMBINED_OFFSET_SELF_TEST */0x00u, 00270 /* AVG_SELF_TEST */0x00u, 00271 /* DEVCFG1 */0x00, 00272 /* Satellite 10 */ 00273 /* PROTOCOL */0x04u, 00274 /* N_DATA_BLOCKS */0x20u, 00275 /* MANUFACTURER */0x46u, 00276 /* SENSOR_TYPE */0x01u, 00277 /* AXIS */0x00u, 00278 /* RANGE */0x09u, 00279 /* DEVCFG2 */0x00u, 00280 /* PRODUCT_REVISION */0x11u, 00281 /* DEVCFG6 */0x00u, 00282 /* PROD_DATE_1 */0x00u, 00283 /* PROD_DATE_2*/0x00u, 00284 /* SN0 */0x00u, 00285 /* SN1 */0x00u, 00286 /* SN2 */0x00u, 00287 /* SN3 */0x00u, 00288 /* INIT_RAW_OFFSET */0x00u, 00289 /* COMBINED_OFFSET_SELF_TEST */0x00u, 00290 /* AVG_SELF_TEST */0x00u, 00291 /* DEVCFG1 */0x00, 00292 /* Satellite 11 */ 00293 /* PROTOCOL */0x04u, 00294 /* N_DATA_BLOCKS */0x20u, 00295 /* MANUFACTURER */0x46u, 00296 /* SENSOR_TYPE */0x01u, 00297 /* AXIS */0x00u, 00298 /* RANGE */0x09u, 00299 /* DEVCFG2 */0x00u, 00300 /* PRODUCT_REVISION */0x11u, 00301 /* DEVCFG6 */0x00u, 00302 /* PROD_DATE_1 */0x00u, 00303 /* PROD_DATE_2*/0x00u, 00304 /* SN0 */0x00u, 00305 /* SN1 */0x00u, 00306 /* SN2 */0x00u, 00307 /* SN3 */0x00u, 00308 /* INIT_RAW_OFFSET */0x00u, 00309 /* COMBINED_OFFSET_SELF_TEST */0x00u, 00310 /* AVG_SELF_TEST */0x00u, 00311 /* DEVCFG1 */0x00, 00312 /* Satellite 12 */ 00313 /* PROTOCOL */0x04u, 00314 /* N_DATA_BLOCKS */0x20u, 00315 /* MANUFACTURER */0x46u, 00316 /* SENSOR_TYPE */0x01u, 00317 /* AXIS */0x00u, 00318 /* RANGE */0x09u, 00319 /* DEVCFG2 */0x00u, 00320 /* PRODUCT_REVISION */0x11u, 00321 /* DEVCFG6 */0x00u, 00322 /* PROD_DATE_1 */0x00u, 00323 /* PROD_DATE_2*/0x00u, 00324 /* SN0 */0x00u, 00325 /* SN1 */0x00u, 00326 /* SN2 */0x00u, 00327 /* SN3 */0x00u, 00328 /* INIT_RAW_OFFSET */0x00u, 00329 /* COMBINED_OFFSET_SELF_TEST */0x00u, 00330 /* AVG_SELF_TEST */0x00u, 00331 /* DEVCFG1 */0x00 }; 00335 const uint8_t cau8SBCSatTestVariableFilter[] = 00336 { 00337 /* PROTOCOL */TRUE, 00338 /* N_DATA_BLOCKS */TRUE, 00339 /* MANUFACTURER */CLEAR, 00340 /* SENSOR_TYPE */TRUE, 00341 /* AXIS */CLEAR, 00342 /* RANGE */CLEAR, 00343 /* DEVCFG2 */CLEAR, 00344 /* PRODUCT_REVISION */CLEAR, 00345 /* DEVCFG6 */CLEAR, 00346 /* PROD_DATE_1 */CLEAR, 00347 /* PROD_DATE_2*/CLEAR, 00348 /* SN0 */CLEAR, 00349 /* SN1 */CLEAR, 00350 /* SN2 */CLEAR, 00351 /* SN3 */CLEAR, 00352 /* INIT_RAW_OFFSET */CLEAR, 00353 /* COMBINED_OFFSET_SELF_TEST */CLEAR, 00354 /* AVG_SELF_TEST */CLEAR, 00355 /* DEVCFG1 */CLEAR, }; 00356 /* 00357 ****************************************************************************** 00358 * Globals 00359 ****************************************************************************** 00360 */ 00362 static uint32_t gu32SBCIgnoredResponse; 00364 uint16_t gu16ActivePSI5Channels; 00366 uint16_t gu16ActiveSquibChannels; 00368 uint16_t gu16FiredSquibs; 00370 uint16_t gu16SquibsToFire; 00372 uint16_t gu16CrashedSatellites; 00374 uint16_t gu16ConfirmedSatellites; 00376 uint32_t gu32SBCTime; 00377 uint8_t gu8SBCSatelliteData[SBC_N_SATELLITES_POSSIBLE * MMA5100_N_REGISTERS]; 00378 /* 00379 ****************************************************************************** 00380 * vfnSBCEnableWarningLamp 00381 * Functional only without any scheduler and 16-bit format 00382 ****************************************************************************** 00383 */ 00384 uint8_t u8fnSBCPreSchedulerEnableWarningLamp(uint8_t u8Enable) 00385 { 00386 /* Turn lamp warning lamp on or off according to passed arg */ 00387 return (u8fnCG147Transcieve(SBC_SET_I_AIO, u8Enable, CG147_SPI_CONFIG)); 00388 } 00389 /* 00390 ****************************************************************************** 00391 * vfnSBCEnableWarningLamp 00392 * Functional with Scheduled SPI Tx in 17-bit configuration ONLY 00393 ****************************************************************************** 00394 */ 00395 uint8_t u8fnSBCEnableWarningLamp(uint8_t u8Enable) 00396 { 00397 /* Turn lamp warning lamp on or off according to passed arg */ 00398 return (u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT, 00399 SBC_SET_I_AIO, u8Enable, 00400 (uint16_t*)&gu32SBCIgnoredResponse, 00401 (uint32_t*)&gu32SBCTime)); 00402 } 00403 /* 00404 ****************************************************************************** 00405 * vfnSBCPreSchedulerInit 00406 * Functional without a scheduler running only. 00407 ****************************************************************************** 00408 */ 00409 void vfnSBCPreSchedulerInit(void) 00410 { 00411 vfnCG147Init(CG147_SPI_CONFIG, DSPI0C6, DSPI0C7, PIN_N_SYS_RES); 00412 /* Keep the lamp on */ 00413 (void)u8fnSBCPreSchedulerEnableWarningLamp(TRUE); 00414 00415 return; 00416 } 00417 /* 00418 ****************************************************************************** 00419 * u8fnSBCInit 00420 * Requires scheduler to be working, switches between 16- to 17-bit config. 00421 ****************************************************************************** 00422 */ 00423 uint32_t u32fnSBCInit(void) 00424 { 00425 uint32_t u32Status; 00426 uint16_t u16LocalStatus; 00427 uint32_t u32LocalStatus; 00428 uint32_t au32LocalSchedResults[SBC_N_CONFIG_BUFFER_SIZE]; 00429 00430 /* Init variables */ 00431 u16LocalStatus = CLEAR; 00432 u32Status = CLEAR; 00433 u32LocalStatus = CLEAR; 00434 00435 /* We should load the active PSI5 satellites from NV memory */ 00436 gu16ActivePSI5Channels = cu16PresentSatellites; 00437 00438 /* Also load the active Squib channels */ 00439 gu16ActiveSquibChannels = cu16PresentSquibs; 00440 00441 /* Do the same for fired squibs */ 00442 gu16FiredSquibs = cu16FiredSquibs; 00443 00444 /* And for crashed satellites */ 00445 gu16CrashedSatellites = cu16CrashedSatellites; 00446 00447 if(SBC_N_CONFIG_BUFFER_SIZE >= cu8CG147InitCmdsArgsSize) 00448 { 00449 /* Transfer all this data in 16-bit mode to the device, followed by a */ 00450 /* switch to 17-bit mode. */ 00451 if(CLEAR == u8fnCG147ScheduleBatchTransfer(CG147_SPI_CONFIG, 00452 (uint8_t*)&cau8CG147InitCmdsIn16Bit, 00453 (uint8_t*)&cau8CG147InitArgsIn16Bit, 00454 (uint16_t*)&au32LocalSchedResults, 00455 cu8CG147InitCmdsArgsSize, 00456 (uint32_t*)&gu32SBCTime)) 00457 { 00458 /* ******** EVERYTHING AFTER HERE MUST BE IN 17-BIT FORMAT ****************/ 00459 /* Now launch Watch-dog timers with default seeds */ 00460 u16LocalStatus = u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT, 00461 SBC_WD2_TRIGGER, 00462 SBC_WD_RESPONSE_8, 00463 (uint16_t*)&gu32CG147WatchDog2RequestToMCU, 00464 (uint32_t*)&gu32SBCTime); 00465 u16LocalStatus |= u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT, 00466 SBC_WD3_TRIGGER, 00467 SBC_WD_RESPONSE_8, 00468 (uint16_t*)&gu32CG147WatchDog3RequestToMCU, 00469 (uint32_t*)&gu32SBCTime); 00470 /* Let's continue if life has been good */ 00471 if(CLEAR == u16LocalStatus) 00472 { 00473 /* Here we wait for the scheduler to send the above SPI frames */ 00474 while(1u > u32fnSchedIsTxDone(gu32SBCTime)) 00475 { 00476 /* Wait here */ 00477 }; 00478 00479 /* We will now gather initial data for our satellites */ 00480 if(MMA5100_SENSOR_READY_STATUS & 00481 u16fnSBCGatherPSI5SatelliteData((uint8_t*)&gu8SBCSatelliteData)) 00482 { 00483 u16LocalStatus = 00484 u16fnSBCTestPSI5SatelliteData((uint8_t*)&gu8SBCSatelliteData, 00485 (uint8_t*)&cu8SBCSatelliteData, 00486 (uint8_t*)&cau8SBCSatTestVariableFilter, 00487 (uint16_t*)&cu16PresentSatellites); 00488 /* Figure out which are our usable squibs based on this */ 00489 gu16ActivePSI5Channels = ((uint16_t)~u16LocalStatus & 00490 cu16PresentSatellites); 00491 00492 /* If the activity above is not transparent, we need to flag it */ 00493 if(gu16ActivePSI5Channels == cu16PresentSatellites) 00494 { 00495 /* Nothing */ 00496 } /* end if - Present satellites match active satellites */ 00497 else 00498 { 00499 /* Flag in status */ 00500 u32Status = (uint32_t)u16LocalStatus; 00501 } /* End else - present satellites do not match active ones */ 00502 00503 /* Run initial tests for the SBC */ 00504 u32LocalStatus = u32fnSBCPerformInitialTests(); 00505 /* Act according to the status of the performed tests which are defined */ 00506 /* within the CG147_Diag.h file. */ 00507 u32Status |= (u32LocalStatus << BITS_IN_16); 00508 if(CLEAR == (u32LocalStatus & SBC_DIAG_CRITICAL_FAILURE)) 00509 { 00510 #ifdef USE_AUTO_SYNC 00511 /* Switch over to CG147-driven Sync-pulses */ 00512 u16LocalStatus = u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT, 00513 SBC_PROG_PSYNC_MODE, 00514 (uint8_t)0xC5u, 00515 (uint16_t*)&gu32SBCIgnoredResponse, 00516 (uint32_t*)&gu32SBCTime); 00517 #else 00518 (void)u8fnSBCSchedulePSync(); 00519 u16LocalStatus = CLEAR; 00520 00521 #endif 00522 /* Stop warning lamp and link it to DIS_ALP status */ 00523 u16LocalStatus |= u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT, 00524 SBC_SET_I_AIO, 00525 (uint8_t)CLEAR, 00526 (uint16_t*)&gu32SBCIgnoredResponse, 00527 (uint32_t*)&gu32SBCTime); 00528 u16LocalStatus |= u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT, 00529 SBC_PROG_AIO_WL, 00530 (uint8_t)0x03u, 00531 (uint16_t*)&gu32SBCIgnoredResponse, 00532 (uint32_t*)&gu32SBCTime); 00533 /* Only continue if we're good to go */ 00534 /* We have finished all configuration. Schedule EOP */ 00535 /* Schedule EOP after config */ 00536 u16LocalStatus |= u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT, 00537 SBC_EOP, 00538 (uint8_t)0x03u, 00539 (uint16_t*)&gu32SBCIgnoredResponse, 00540 (uint32_t*)&gu32SBCTime); 00541 /* We're about to leave */ 00542 if(CLEAR == u16LocalStatus) 00543 { 00544 /* Done */ 00545 DELAY_MSEC(1u); 00546 } 00547 else 00548 { 00549 /* We're bruised */ 00550 u32Status |= SBC_TEST_SCHEDULER_FAILED; 00551 } 00552 } /* End if - initial SBC tests were passed */ 00553 else 00554 { 00555 u32Status |= SBC_TEST_SBC_FAILED; 00556 } 00557 } /* End if - satellites responded "ready" */ 00558 else 00559 { 00560 /* Satellites did not initialize correctly */ 00561 u32Status = SBC_TEST_ALL_SAT; 00562 } /* End else - satellites did not respond as "ready" */ 00563 } /* End if - Scheduled WD data correctly. */ 00564 else 00565 { 00566 /* Problem scheduling data. Exit with error code */ 00567 u32Status = SBC_TEST_SCHEDULER_FAILED; 00568 } /* End else - WD scheduled incorrectly */ 00569 } /* End if - 16-bit operations occurred successfully */ 00570 else 00571 { 00572 u32Status = SBC_TEST_UNEXPECTED_SPI_RESULT; 00573 } /* End else: 16-bit operations did not occur successfully */ 00574 } /* End if - IntCmds and args is correct */ 00575 else 00576 { 00577 /* Programming error - go fix it */ 00578 u32Status = 0xFFFFFFFF; 00579 } /* End else - IntCmds and Args is not correct */ 00580 return (u32Status); 00581 } 00582 /* 00583 ****************************************************************************** 00584 * u32fnSBCPerformInitialTests 00585 * Functional with Scheduled SPI Tx in 17-bit configuration ONLY 00586 ****************************************************************************** 00587 */ 00588 uint32_t u32fnSBCPerformInitialTests(void) 00589 { 00590 /* General Status */ 00591 uint32_t u32Status; 00592 uint8_t u8Counter; 00593 uint8_t u8TestCounter; 00594 00595 00596 u32Status = CLEAR; 00597 00598 /* Perform POM tests */ 00599 for(u8Counter = CLEAR; u8Counter < CG147_N_ER_LINES; u8Counter++) 00600 { 00601 for(u8TestCounter = CLEAR; u8TestCounter < cu8SizeOfSBCTests; 00602 u8TestCounter++) 00603 { 00604 u32Status |= u32fnSBCPerformInitialTestsPOM(u8Counter, u8TestCounter); 00605 } 00606 } 00607 /* At this point, we know whether the SBC is reliable or not as a unit */ 00608 if(CLEAR == u32Status) 00609 { 00610 /* Next perform ADC, Mux tests */ 00611 for(u8Counter = CLEAR; u8Counter < cu8SizeOfTestAnaHeadSettings; 00612 u8Counter++) 00613 { 00614 u32Status |= u32fnSBCTestMuxAndADC(u8Counter); 00615 } 00616 00617 if(((CG147_END_OF_PROGRAMMING_FLAG >> BITS_IN_BYTE) == u32Status) || 00618 (CLEAR == u32Status)) 00619 { 00620 /* Continue with FLM tests which will tell us if our squibs are ok */ 00621 u32Status = u32fnSBCPerformInitialTestsFLM(gu16ActiveSquibChannels); 00622 } 00623 else 00624 { 00625 u32Status = SBC_TEST_SBC_FAILED; 00626 } 00627 } 00628 else 00629 { 00630 u32Status = SBC_TEST_SBC_FAILED; 00631 } 00632 return (u32Status); 00633 } 00634 /* 00635 ****************************************************************************** 00636 * u16fnSBCGatherPSI5SatelliteData 00637 * Functional with Scheduled SPI Tx in 17-bit configuration ONLY 00638 ****************************************************************************** 00639 */ 00640 uint16_t u16fnSBCGatherPSI5SatelliteData(uint8_t* pu8PSI5Data) 00641 { 00642 /* Local variables */ 00643 /* for loop counters */ 00644 uint16_t u16Counter1; 00645 uint16_t u16Counter2; 00646 /* Temporary array for 16-bit data */ 00647 uint16_t au16SBCSensorSettings[SBC_N_SATELLITES_POSSIBLE 00648 * SBC_SENSOR_DATA_ARRAY_SIZE]; 00649 /* Index memory per data-nibble received */ 00650 uint8_t au8SatIndex[SBC_N_SATELLITES_POSSIBLE]; 00651 uint8_t au8SatIndexAdder[SBC_N_SATELLITES_POSSIBLE]; 00652 uint32_t au32SatAlreadyWrittenMem[SBC_N_SATELLITES_POSSIBLE]; 00653 /* Array to receive acceleration data */ 00654 uint32_t au32TempRawDataDepot[5u]; 00655 /* Mask used in inner for loop */ 00656 uint16_t u16Mask; 00657 /* Status register */ 00658 uint16_t u16Status; 00659 00660 /* Init locals */ 00661 u16Mask = CG147_SAT_MASK_MIN; 00662 u16Status = CLEAR; 00663 for(u16Counter1 = CLEAR; u16Counter1 < N_ELEMENTS(au32TempRawDataDepot); u16Counter1++) 00664 { 00665 au32TempRawDataDepot[u16Counter1] = CLEAR; 00666 } 00667 for(u16Counter1 = CLEAR; u16Counter1 < N_ELEMENTS(au16SBCSensorSettings); u16Counter1++) 00668 { 00669 au16SBCSensorSettings[u16Counter1] = CLEAR; 00670 } 00671 for(u16Counter1 = CLEAR; u16Counter1 < SBC_N_SATELLITES_POSSIBLE; u16Counter1++) 00672 { 00673 au8SatIndex[u16Counter1] = CLEAR; 00674 au8SatIndexAdder[u16Counter1] = CLEAR; 00675 au32SatAlreadyWrittenMem[u16Counter1] = CLEAR; 00676 } 00677 00678 /* Wait for satellites to wake-up */ 00679 DELAY_MSEC(195u); 00680 00681 /* We will now gather and treat all data */ 00682 for(u16Counter1 = CLEAR; u16Counter1 < N_ELEMENTS(au16SBCSensorSettings); 00683 u16Counter1 += SBC_N_SATELLITES_POSSIBLE) 00684 { 00685 /* Generate PSI5 sync pulse */ 00686 vfnCG147SyncPulse(PIN_N_SYNC); 00687 SCHED_WHAT_IS_THE_TIME(gu32SBCTime); 00688 while (SCHED_500US_PERIOD > u32fnSchedHasTimeElapsed(gu32SBCTime)) 00689 { 00690 /* Wait for two clicks to pass */ 00691 } 00692 00693 /* First, we need to gather data from satellites */ 00694 (void)u32fnSBCSchedulePSISat((uint16_t*)&au32TempRawDataDepot); 00695 00696 /* Reset mask for operations coming up */ 00697 u16Mask = CG147_SAT_MASK_MIN; 00698 00699 while (1u > u32fnSchedIsTxDone(gu32SBCTime)) 00700 { 00701 /* Wait for one click to pass */ 00702 00703 } 00704 00705 /* We have started getting data. Decode whatever we got in 32-bit to 16-bit format. */ 00706 (void)u16fnCG147ExtractScheduledPSI5Accel((uint32_t*)&au32TempRawDataDepot, 00707 (uint16_t*)&(au16SBCSensorSettings[u16Counter1]), 00708 gu16ActivePSI5Channels); 00709 00710 /* Next, we will figure out what this data means */ 00711 for(u16Counter2 = CLEAR; u16Counter2 < SBC_N_SATELLITES_POSSIBLE; u16Counter2++) 00712 { 00713 /* Only if the satellite channel is active */ 00714 if(gu16ActivePSI5Channels & u16Mask) 00715 { 00716 u16Status |= u16fnMMA5100TreatData((uint16_t*)&(au16SBCSensorSettings[u16Counter1 + u16Counter2]), 00717 (uint8_t*)&(pu8PSI5Data[(u16Counter2 * MMA5100_N_REGISTERS)]), 00718 (uint8_t*)&(au8SatIndex[u16Counter2]), 00719 (uint8_t*)&(au8SatIndexAdder[u16Counter2]), 00720 (uint32_t*)&(au32SatAlreadyWrittenMem[u16Counter2])); 00721 } 00722 else 00723 { 00724 /* Inactive sensor channel */ 00725 } 00726 u16Mask <<= BIT0; 00727 } 00728 00729 } 00730 return(u16Status); 00731 } 00732 /* 00733 ****************************************************************************** 00734 * u16fnSBCTestPSI5SatelliteData 00735 * Functional with Scheduled SPI Tx in 17-bit configuration ONLY 00736 ****************************************************************************** 00737 */ 00738 static uint16_t u16fnSBCTestPSI5SatelliteData(const uint8_t* au8SBCSatData, 00739 const uint8_t* au8SBCSatBasis, 00740 const uint8_t* au8SBCSatTestFilt, 00741 const uint16_t* pu16ActiveSat) 00742 { 00743 uint16_t u16Status; 00744 uint16_t u16Mask; 00745 uint8_t u8Counter1; 00746 uint8_t u8Counter2; 00747 uint16_t u16LocalIndex; 00748 00749 u16Status = CLEAR; 00750 00751 u16Mask = CG147_SAT_MASK_MIN; 00752 00753 for(u8Counter1 = CLEAR; u8Counter1 < SBC_N_SATELLITES_POSSIBLE; u8Counter1++) 00754 { 00755 if(u16Mask & *pu16ActiveSat) 00756 { 00757 for(u8Counter2 = CLEAR; u8Counter2 < MMA5100_N_REGISTERS; u8Counter2++) 00758 { 00759 if(TRUE == au8SBCSatTestFilt[u8Counter2]) 00760 { 00761 u16LocalIndex = ((uint16_t)(MMA5100_N_REGISTERS * u8Counter1) + 00762 (uint16_t)u8Counter2); 00763 if(au8SBCSatData[u16LocalIndex] == au8SBCSatBasis[u16LocalIndex]) 00764 { 00765 /* This is good - we passed the test */ 00766 } 00767 else 00768 { 00769 /* This is bad - we failed the test and must report it */ 00770 u16Status |= (BIT0 << u8Counter1); 00771 } 00772 } 00773 else 00774 { 00775 /* No test to perform */ 00776 } 00777 } 00778 } 00779 else 00780 { 00781 /* Skip */ 00782 } 00783 u16Mask <<= BIT0; 00784 } 00785 00786 return (u16Status); 00787 } 00788 /* 00789 ****************************************************************************** 00790 * u32fnSBCSchedulePSISat 00791 * Functional with Scheduled SPI Tx in 17-bit configuration ONLY 00792 ****************************************************************************** 00793 */ 00794 uint32_t u32fnSBCSchedulePSISat(uint16_t* pu16RawAccelArray) 00795 { 00796 uint32_t u32Status; 00797 00798 u32Status = u8fnCG147ScheduleSafePSI5Accel(CG147_SPI_CONFIG_EXT_MONITORING, 00799 gu16ActivePSI5Channels, 00800 (uint32_t*)pu16RawAccelArray, 00801 (uint32_t*)&gu32SBCTime); 00802 00803 if(u32Status != CLEAR) 00804 { 00805 u32Status = STATUS_SCHEDULER_PROBLEM; 00806 } 00807 else 00808 { 00809 /* Nothing to do */ 00810 } 00811 return (u32Status); 00812 } 00813 /* 00814 ****************************************************************************** 00815 * u8fnSBCSchedulePSync 00816 * Functional with Scheduled SPI Tx in 17-bit configuration ONLY 00817 ****************************************************************************** 00818 */ 00819 uint8_t u8fnSBCSchedulePSync(void) 00820 { 00821 return(u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT, 00822 SBC_PSI_SYNC_GEN, 00823 CLEAR, 00824 (uint16_t*)&gu32SBCIgnoredResponse, 00825 (uint32_t*)&gu32SBCTime)); 00826 } 00827 /* 00828 ****************************************************************************** 00829 * u8fnSBCSyncSM 00830 * Functional with Scheduler 00831 ****************************************************************************** 00832 */ 00833 uint8_t u8fnSBCSyncSM(const uint8_t cu8Period) 00834 { 00835 uint8_t u8Status; 00836 00837 u8Status = CLEAR; 00838 00839 while(cu8Period != gu16CG147WatchDog2IsrCount) 00840 { 00841 /* Wait */ 00842 } 00843 00844 return(u8Status); 00845 } 00846 /* 00847 ****************************************************************************** 00848 * u32fnSBCExtractPSISat 00849 * Functional with Scheduled SPI Tx in 17-bit configuration ONLY 00850 ****************************************************************************** 00851 */ 00852 uint32_t u32fnSBCExtractPSISat(uint16_t* pu16RawAccelArray, 00853 uint16_t* pu16Filtered) 00854 { 00855 uint32_t u32Status; 00856 uint8_t u8Index; 00857 00858 u32Status = u16fnCG147ExtractScheduledPSI5Accel((uint32_t*)pu16RawAccelArray, 00859 pu16Filtered, 00860 gu16ActivePSI5Channels); 00861 /* Filter signed data to unsigned centered at 512 cts */ 00862 for(u8Index = CLEAR; u8Index < SBC_N_SATELLITES_POSSIBLE; u8Index++) 00863 { 00864 if((*pu16Filtered >= MMA5100_UL_FOR_DATA) 00865 || (*pu16Filtered <= MMA5100_LL_FOR_STATUS)) 00866 { 00867 /* We are happy */ 00868 *pu16Filtered = u16fn10BitOffsetFilter(*pu16Filtered); 00869 } 00870 else 00871 { 00872 u32Status |= ((gu16ActivePSI5Channels) & (BIT0 << u8Index)); 00873 *pu16Filtered = 0x021Fu; 00874 } 00875 00876 pu16Filtered++; 00877 } 00878 00879 return (u32Status); 00880 } 00881 /* 00882 ****************************************************************************** 00883 * u32fnSBCScheduleCmd 00884 * Functional with Scheduled SPI Tx in 17-bit configuration ONLY 00885 ****************************************************************************** 00886 */ 00887 uint32_t u32fnSBCScheduleCmd(uint8_t u8Cmd, uint8_t u8Arg, 00888 uint16_t* pu16Response) 00889 { 00890 uint32_t u32Status; 00891 u32Status = u8fnCG147ScheduleSafeTransfer( CG147_SPI_CONFIG_EXT, u8Cmd, u8Arg, 00892 pu16Response, 00893 (uint32_t*)&gu32SBCTime); 00894 if(CLEAR == u32Status) 00895 { 00896 /* leave */ 00897 } 00898 else 00899 { 00900 /* Flag it as a problem */ 00901 u32Status = STATUS_SCHEDULER_PROBLEM; 00902 } 00903 00904 return (u32Status); 00905 } 00906 /* 00907 ****************************************************************************** 00908 * u32fnSBCFireSquibs 00909 * Functional with Scheduled SPI Tx in 17-bit configuration ONLY 00910 ****************************************************************************** 00911 */ 00912 uint32_t u32fnSBCFireSquibs(const uint16_t cu16SquibMask) 00913 { 00914 uint32_t u32Status; 00915 00916 /* There's no case in executing this fn if the mask is empty */ 00917 if(CLEAR != cu16SquibMask) 00918 { 00919 u32Status = u8fnCG147ScheduleSafeSquibFireStart(CG147_SPI_CONFIG_EXT, 00920 cu16SquibMask, 00921 (uint32_t*)&gu32SBCTime); 00922 if(CLEAR != u32Status) 00923 { 00924 u32Status = STATUS_SCHEDULER_PROBLEM; 00925 } 00926 else 00927 { 00928 /* Continue */ 00929 00930 /* Wait for Squibs to fire */ 00931 DELAY_MSEC(2u); 00932 00933 /* Stop firing squibs */ 00934 u32Status = u8fnCG147ScheduleSafeSquibFireStop(CG147_SPI_CONFIG_EXT, 00935 (uint32_t*)&gu32SBCTime); 00936 if(CLEAR != u32Status) 00937 { 00938 u32Status = STATUS_SCHEDULER_PROBLEM; 00939 } 00940 else 00941 { 00942 /* Nothing */ 00943 } 00944 } 00945 } 00946 else 00947 { 00948 /* Get out */ 00949 u32Status = CLEAR; 00950 } 00951 00952 return (u32Status); 00953 } 00954 /* 00955 ****************************************************************************** 00956 * u32fnSBCSquibFiringStatus 00957 * Functional with Scheduled SPI Tx in 17-bit configuration ONLY 00958 ****************************************************************************** 00959 */ 00960 uint32_t u32fnSBCSquibFiringStatus(uint16_t* pu16Response) 00961 { 00962 uint32_t u32Status; 00963 uint8_t u8LocalStatus; 00964 uint8_t u8Index; 00965 uint32_t au32LocalResults[N_ELEMENTS(cau8SBCSquibFiringStatusCmd)]; 00966 uint8_t au8LocalResults[N_ELEMENTS(cau8SBCSquibFiringStatusCmd)]; 00967 00968 u32Status = u8fnCG147ScheduleSafeBatchTransfer(CG147_SPI_CONFIG_EXT, 00969 (uint8_t*)cau8SBCSquibFiringStatusCmd, 00970 (uint8_t*)cau8SBCSquibFiringStatusArg, 00971 (uint16_t*)au32LocalResults, 00972 N_ELEMENTS(cau8SBCSquibFiringStatusCmd), 00973 (uint32_t*)&gu32SBCTime); 00974 00975 /* Init some variables while we wait for the transfer to occur */ 00976 *pu16Response = CLEAR; 00977 u8LocalStatus = CLEAR; 00978 u8Index = CLEAR; 00979 00980 /* Continue only if the transfer was scheduled correctly */ 00981 if(u32Status == CLEAR) 00982 { 00983 while(1u > u32fnSchedIsTxDone(gu32SBCTime)) 00984 { 00985 /* Wait here for the transfer to happen */ 00986 }; 00987 00988 /* We will ignore the first response since, according to the CG147's */ 00989 /* spec, it contains unknown data. */ 00990 for(; u8Index < (N_ELEMENTS(cau8SBCSquibFiringStatusCmd) - 1u); 00991 u8Index++) 00992 { 00993 u8LocalStatus = u8fnCG147ExtractResponse((uint32_t*)&au32LocalResults[u8Index + 1u], 00994 (uint8_t*)&au8LocalResults[u8Index]); 00995 00996 if(CLEAR == u8LocalStatus) 00997 { 00998 if(au8LocalResults[u8Index] > SBC_FIRED_SQUIB_MIN_TIME) 00999 { 01000 *pu16Response |= (BIT0 << (u8Index)); 01001 } 01002 else 01003 { 01004 /* Nothing */ 01005 } /* end else Min time surpassed */ 01006 } /* End if u32TempStatus is clear */ 01007 else 01008 { 01009 /* Failed. Leave */ 01010 u32Status = STATUS_DATA_TRANSFER_ERROR; 01011 break; 01012 } /* End else u32TempStatus is (not) clear */ 01013 } 01014 /* End FOR */ 01015 } 01016 else 01017 { 01018 /* Exit */ 01019 u32Status = STATUS_SCHEDULER_PROBLEM; 01020 } 01021 return (u32Status); 01022 } 01023 /* 01024 ****************************************************************************** 01025 * 01026 * End of file. 01027 * 01028 ****************************************************************************** 01029 */